package com.tsj.model.utils;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;


import java.sql.Types;
import java.util.*;

/**
 * <p>
 * MybatisPlus的代码生成工具
 * 官方配置文档地址https://baomidou.com/reference/new-code-generator-configuration/
 * <p>
 *
 * @author taoshujian
 * @version 1.0
 * @since 2025-09-26 23:33:12
 */
public class MybatisPlusCodeGenerator {

    // 数据库配置
    private static final String DB_URL = "jdbc:mysql://localhost:3306/tsj-wc?useSSL=false&serverTimezone=UTC&characterEncoding=utf8";
    private static final String DB_USERNAME = "root";
    private static final String DB_PASSWORD = "123456";

    // 项目配置
    private static final String PROJECT_PACKAGE = "com.tsj.model.auto";
    private static final String AUTHOR = "taoshujian";
    private static final String OUTPUT_DIR = System.getProperty("user.dir") + "/src/main/java";

    // 需要生成代码的表名
    private static final List<String> TABLE_NAMES = List.of("website");

    public static void main(String[] args) {
        FastAutoGenerator.create(DB_URL, DB_USERNAME, DB_PASSWORD)
                .globalConfig(builder -> {
                    builder.author(AUTHOR) // 设置作者
                            //.enableSwagger() // 开启 swagger 模式
                            .outputDir(OUTPUT_DIR) // 指定输出目录
                            .commentDate("yyyy-MM-dd HH:mm:ss") // 设置注释日期格式
                            .disableOpenDir(); // 关闭默认的打开目录
                })
                .dataSourceConfig(builder ->
                        builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                            int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                            if (typeCode == Types.SMALLINT) {
                                // 自定义类型转换
                                return DbColumnType.INTEGER;
                            }
                            return typeRegistry.getColumnType(metaInfo);
                        })
                )
                .packageConfig(builder ->
                        builder.parent(PROJECT_PACKAGE) // 设置父包名
                                .entity("model.entity") //默认值: entity
                                .mapper("mapper") // 默认值: mapper
                                .service("service") //默认值: service
                                .controller("controller") //默认值: controller
                                .serviceImpl("service.impl")// 默认值: service.impl
                )
                .strategyConfig(builder ->
                        builder.addInclude(TABLE_NAMES) // 设置需要生成的表名
                                .addTablePrefix("t_", "c_") // 设置过滤表前缀
                                .entityBuilder()
                                .enableLombok() // 启用 Lombok
                                .enableTableFieldAnnotation() // 启用字段注解
                                .controllerBuilder()
                                .enableRestStyle()// 启用 REST 风格
                )
                .strategyConfig (builder ->
                        builder.entityBuilder()
                                .javaTemplate("/templates/entity.java") // 设置实体类模板
                                //.serviceBuilder()
                                //.disableServiceImpl() // 禁用 ServiceImpl 层生成
                                //.disableService() // 禁用 Service 层生成
                                .mapperBuilder().disableMapperXml() // 禁用 Mapper XML 层生成
                                //.controllerBuilder().disable() // 禁用 Controller 层生成

                )
                // 自定义模板，如 DTO (Data Transfer Object) 和 VO (Value Object)
                .injectionConfig  (injectConfig  ->{
                        Map<String,Object> customMap = new HashMap<>();
                        customMap.put("abc","1234");
                        // 输入DTO的完整包路径
                        customMap.put("inputPackage", PROJECT_PACKAGE+".model.input");
                            // 输出DTO的完整包路径
                        customMap.put("outputPackage", PROJECT_PACKAGE+".model.output");
                        injectConfig.customMap(customMap); //注入自定义属性
                        List<CustomFile> customFiles = Arrays.asList(
                                new CustomFile.Builder()
                                .fileName("AddInput.java") //文件名称
                                .templatePath("templates/entityAddInput.java.ftl") //指定生成模板路径
                                .packageName("model.input") //包名,自3.5.10开始,可通过在package里面获取自定义包全路径,低版本下无法获取,示例:package.entityDTO
                                .build(),
                                new CustomFile.Builder()
                                .fileName("UpdateInput.java")
                                .templatePath("templates/entityUpdateInput.java.ftl")
                                .packageName("model.input")
                                .build());
                        injectConfig.customFile(customFiles);
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }
}
